package com.wtwd.campus.attendancereceiver;

import com.wtwd.campus.annotation.MsgType;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.entity.*;
import com.wtwd.campus.receiver.IReceiverHandler;
import com.wtwd.campus.service.AttendanceProductService;
import com.wtwd.campus.service.AttendanceRulesService;
import com.wtwd.campus.service.DeviceInfoService;
import com.wtwd.campus.service.StudentService;
import com.wtwd.campus.utils.AttendanceCommandUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
@MsgType(value = Constants.SEND_DATA)
public class AttendanceSendDataHandler implements IReceiverHandler {
    private static final Logger logger = LoggerFactory.getLogger(AttendanceSendDataHandler.class);

    @Autowired
    private AttendanceProductService attendanceService;
    @Autowired
    private AttendanceCommandUtils attendanceCommandUtils;
    @Autowired
    private AttendanceRulesService attendanceRulesService;
    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private StudentService studentService;

    @Override
    public void handlerMessage(MqMessage mqMessage) {
        AttendanceSendDataList attendanceSendDataList = (AttendanceSendDataList) mqMessage.getObject();
        if (!StringUtils.isBlank(attendanceSendDataList.getProductNo())) {
            AttendanceProduct attendance = attendanceService.getAttendanceProductByProNo(attendanceSendDataList.getProductNo());
            if (attendance != null) {
                List<AttendanceSendData> list = attendanceSendDataList.getList();
                List<Map<String, Object>> metaList = new ArrayList<>();
                List<AttendanceRecordData> addRecordList=new ArrayList<>();
                List<AttendanceRecordData> modifyRecordList=new ArrayList<>();
                list.stream().forEach(e -> {
                    //存储每一个学生考勤记录
                    //根据rfid找到学生id
                    DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByRfid(e.getCardNo());
                    if (deviceInfo != null && deviceInfo.getStudentId() != null) {
                        Map<String, Object> map = new HashMap<>();
                        map.put("studentId", deviceInfo.getStudentId());
                        map.put("rfid", deviceInfo.getRfid());
                        map.put("time", e.getTime());
                        map.put("productNo", attendanceSendDataList.getProductNo());
                        map.put("serialNo", attendanceSendDataList.getSerialNo());
                        map.put("status", e.getStatus());
                        metaList.add(map);
/*                        //临时测试，设置时间
                        e.setTime(1642408777000l);*/
                        //根据考勤规则存储考勤记录
                        List<Object> attendanceData = saveAttendanceRecord(e, attendanceSendDataList, deviceInfo.getStudentId(), deviceInfo.getDeviceId());
                        if (attendanceData!=null){
                            if((Integer)attendanceData.get(0) == 0){
                                modifyRecordList.add((AttendanceRecordData)attendanceData.get(1));
                            }else{
                                addRecordList.add((AttendanceRecordData)attendanceData.get(1));
                            }
                        }
                    }
                });
                //批量新增考勤原数据记录
                if (metaList.size() > 0) {
                    attendanceRulesService.saveAttendanceMetaRecordList(metaList);
                }
                //批量新增和修改考勤记录
                if (addRecordList.size()>0){
                    attendanceRulesService.addAttendanceRecord(addRecordList);
                    logger.info("新增一批考勤记录：data = {}",addRecordList.toString());
                }
                if (modifyRecordList.size()>0){
                    attendanceRulesService.modifyAttendanceRecord(modifyRecordList);
                    logger.info("修改一批考勤记录：data = {}",addRecordList.toString());
                }
                //回复考勤机
                attendanceCommandUtils.sendDataReply(attendanceSendDataList.getSerialNo(), attendanceSendDataList.getProductNo());
            } else {
                logger.info("考勤机未入库，信息无法保存：{}", attendanceSendDataList.getList().toString());
            }
        } else {
            logger.info("无法获取上报打卡信息的考勤机编号，故无法回复");
        }
    }

    /**
     * 存储考勤记录
     */
    public List<Object> saveAttendanceRecord(AttendanceSendData data, AttendanceSendDataList listData, Integer stuId, Integer deviceId) {
        List<Object> result=new ArrayList<>();
        //查询该学生当天的考勤规则
        int[] arr = {7, 1, 2, 3, 4, 5, 6};
        Long time = data.getTime();
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        int week = arr[calendar.get(Calendar.DAY_OF_WEEK) - 1];
        Map<String, Object> stuMess = studentService.getSchoolIdAndClassIdByStuId(stuId);
        Integer schoolId = (Integer) stuMess.get("id");
        Integer gradeId = (Integer) stuMess.get("grade_id");
        Map<String, Object> rules = attendanceRulesService.getRulesByCondition(week, schoolId,gradeId);
        //获取今天签到时间的时分形式
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        String timeStr = sdf.format(date);
        if (rules != null) {
            //获取该学生当天的打卡记录
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND,0);
            long dayTime = calendar.getTimeInMillis();
            AttendanceRecordData attendanceRecord = attendanceRulesService.getAttendanceRecordByCondition(dayTime, stuId);
            int addOrModify=0;
            if (attendanceRecord == null) {
                attendanceRecord = new AttendanceRecordData();
                attendanceRecord.setStudentId(stuId);
                attendanceRecord.setRfid(data.getCardNo());
                attendanceRecord.setTime(dayTime);
                attendanceRecord.setDeviceId(deviceId);
                attendanceRecord.setSignMorning(4);
                attendanceRecord.setLeaveMorning(4);
                attendanceRecord.setSignAfternoon(4);
                attendanceRecord.setLeaveAfternoon(4);
                addOrModify=1;
            }
            //比较上午签到打卡状态
            if ((Integer) rules.get("sign_morning_select") == 1 && attendanceRecord.getSignMorning()== 4 && data.getStatus() == 1) {
                //计算迟到时间
                String signMorningEnd = (String) rules.get("sign_morning_end");
                Integer beLate = (Integer) rules.get("be_late");
                String lateTime = calculateBeLateTime(signMorningEnd, beLate);
                //正常上午签到时间
                if (timeStr.compareTo((String) rules.get("sign_morning_begin")) >= 0 && timeStr.compareTo((String) rules.get("sign_morning_end")) <= 0) {
                    //上午正常
                    attendanceRecord.setSignMorning(0);
                    attendanceRecord.setSignMorningTime(data.getTime());
                } else if (timeStr.compareTo((String) rules.get("sign_morning_end")) > 0 && timeStr.compareTo(lateTime)<=0) {
                    //上午签到迟到
                    attendanceRecord.setSignMorning(2);
                    attendanceRecord.setSignMorningTime(data.getTime());
                } else if(timeStr.compareTo(lateTime)>0){
                    //上午未打卡
                    attendanceRecord.setSignMorning(1);
                }
            }

            //比较上午签退打卡状态
            if ((Integer) rules.get("leave_morning_select") == 1 && attendanceRecord.getLeaveMorning()== 4 && data.getStatus() == 2) {
                //计算早退时间
                String leaveMorningBegin = (String) rules.get("leave_morning_begin");
                Integer leaveEarly = (Integer) rules.get("leave_early");
                String lateTime = calculateLeaveEarlyTime(leaveMorningBegin, leaveEarly);
                //正常上午签退时间
                if (timeStr.compareTo((String) rules.get("leave_morning_begin")) >= 0 && timeStr.compareTo((String) rules.get("leave_morning_end")) <= 0) {
                    //上午正常签退
                    attendanceRecord.setLeaveMorning(0);
                    attendanceRecord.setLeaveAfternoonTime(data.getTime());
                } else if (timeStr.compareTo((String) rules.get("leave_morning_begin")) < 0 && timeStr.compareTo(lateTime)>=0) {
                    //上午早退
                    attendanceRecord.setLeaveMorning(2);
                    attendanceRecord.setLeaveAfternoonTime(data.getTime());
                } else if(timeStr.compareTo((String) rules.get("leave_morning_end"))>0){
                    //未签退
                    attendanceRecord.setLeaveMorning(1);
                }
            }

            //比较下午签到打卡状态
            if ((Integer) rules.get("sign_afternoon_select") == 1 && attendanceRecord.getSignAfternoon()== 4 && data.getStatus() == 1) {
                //计算迟到时间
                String signAfternoonEnd = (String) rules.get("sign_afternoon_end");
                Integer beLate = (Integer) rules.get("be_late");
                String lateTime = calculateBeLateTime(signAfternoonEnd, beLate);
                //正常下午签到时间
                if (timeStr.compareTo((String) rules.get("sign_afternoon_begin")) >= 0 && timeStr.compareTo((String) rules.get("sign_afternoon_end")) <= 0) {
                    //下午正常签到
                    attendanceRecord.setSignAfternoon(0);
                    attendanceRecord.setSignAfternoonTime(data.getTime());
                } else if (timeStr.compareTo((String) rules.get("sign_afternoon_end")) > 0 && timeStr.compareTo(lateTime)<=0) {
                    //下午签到迟到
                    attendanceRecord.setSignAfternoon(2);
                    attendanceRecord.setSignAfternoonTime(data.getTime());
                } else if(timeStr.compareTo(lateTime)>0){
                    //下午未签到
                    attendanceRecord.setSignAfternoon(1);
                }
            }

            //比较下午签退打卡状态
            if ((Integer) rules.get("leave_afternoon_select") == 1 && attendanceRecord.getLeaveAfternoon()== 4 && data.getStatus() == 2) {
                //计算早退时间
                String leaveAfternoonBegin = (String) rules.get("leave_afternoon_begin");
                Integer leaveEarly = (Integer) rules.get("leave_early");
                String earlyTime = calculateLeaveEarlyTime(leaveAfternoonBegin, leaveEarly);
                //正常下午签退时间
                if (timeStr.compareTo((String) rules.get("leave_afternoon_begin")) >= 0 && timeStr.compareTo((String) rules.get("leave_afternoon_end")) <= 0) {
                    //下午正常签退
                    attendanceRecord.setLeaveAfternoon(0);
                    attendanceRecord.setLeaveAfternoonTime(data.getTime());
                } else if (timeStr.compareTo((String) rules.get("leave_afternoon_begin")) < 0 && timeStr.compareTo(earlyTime)>=0) {
                    //下午早退
                    attendanceRecord.setLeaveAfternoon(2);
                    attendanceRecord.setLeaveAfternoonTime(data.getTime());
                } else if(timeStr.compareTo((String) rules.get("leave_afternoon_end"))>0){
                    //下午未签退
                    attendanceRecord.setLeaveAfternoon(1);
                }
            }
            result.add(addOrModify,attendanceRecord);
            return result;
        }
        return null;
    }

    /**
     * 计算迟到时间
     * @return
     */
    public String calculateBeLateTime(String time,Integer late){
        Integer hourInt = Integer.valueOf((String) time.substring(0, 2));
        Integer minInt = Integer.valueOf((String) time.substring(3, 5));
        String lateTime="";
        if (minInt + late == 60) {
            hourInt+=1;
            lateTime=String.valueOf(hourInt).concat(":").concat("00");
        }else if(minInt + late >60){
            hourInt+=1;
            minInt=minInt + late-60;
            lateTime=String.valueOf(hourInt).concat(":").concat(String.valueOf(minInt));
        }else  {
            minInt= minInt + late;
            lateTime=String.valueOf(hourInt).concat(":").concat(String.valueOf(minInt));
        }
        return lateTime;
    }

    /**
     * 计算早退时间
     * @return
     */
    public String calculateLeaveEarlyTime(String time,Integer late){
        Integer hourInt = Integer.valueOf((String) time.substring(0, 2));
        Integer minInt = Integer.valueOf((String) time.substring(3, 5));
        String lateTime="";
        if (minInt - late == 0) {
            lateTime=String.valueOf(hourInt).concat(":").concat("00");
        }else if(late - minInt > 0){
            hourInt-=1;
            minInt=60-(late-minInt);
            lateTime=String.valueOf(hourInt).concat(":").concat(String.valueOf(minInt));
        }else {
            minInt=minInt - late;
            lateTime=String.valueOf(hourInt).concat(":").concat(String.valueOf(minInt));
        }
        return lateTime;
    }


    public static void main(String[] args) {
        Long time = 1642408777000l;
        Date date = new Date(time);
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        String timeStr = sdf.format(date);
        System.out.println(timeStr);
       /* Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        System.out.println(calendar.get(Calendar.MINUTE));
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("hh:MM");
        String format = sdf.format(date);
        System.out.println(format);
        String a = "08:12";
        String b = "08:12";
        System.out.println(a.compareTo(b));

        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        long timeInMillis = calendar.getTimeInMillis();
        System.out.println(timeInMillis);*/
    }

}
